function result = mimo_decode(a, decode_method, snr, d, e, f, g, flag_use_random)
    % a: the number of data
    % decode_method: 1 for 4qam, 2 for 4ask, 3 for 4fsk
    % snr: signal noise ratio
    % d, e, f, g: bit stream value
    % flag_use_random: 1 for using random value, 0 for using d, e, f, g

    n = a;
    h = sqrt(1/2) * (randn(n, 2) + 1i * randn(n, 2));
    w = sqrt(1/2) * (randn(n, 2) + 1i * randn(n, 2));
    c1 = zeros(1, 4);
    rcc1 = [0, 0, 0, 0];

    if (flag_use_random == 1)
        c1 = [d, e, f, g];
    else
        c1 = unifrnd(0, 1, 1, 4);
        c1 = c1 >= 0.5;
    end

    m = complex(zeros(1, 4));
    %%4qam
    if (decode_method == 1)
        %4qam
        N = length(c1);
        n = N / 2;

        for i = 1:n

            if (c1(2 * i - 1) == 0)

                if (c1(2 * i) == 0)
                    m(i) = (1 + 1i) / sqrt(2);
                else
                    m(i) = (-1 + 1i) / sqrt(2);
                end

            else

                if (c1(2 * i) == 0)
                    m(i) = (-1 - 1i) / sqrt(2);
                else
                    m(i) = (1 - 1i) / sqrt(2);
                end

            end

        end

        cc1 = m;

        %Alamouti
        m1 = cc1(1);
        m2 = -conj(cc1(2));
        m3 = cc1(2);
        m4 = conj(cc1(1));
        s1 = [m1, m2; m3, m4];

        %recieve
        y1 = sqrt(10 ^ (snr / 10) / 2) * h * s1 + w;

        %decode
        % s = complex(zeros(1, 4));
        % s(1) = (1 + 1i) / sqrt(2);
        % s(2) = (-1 + 1i) / sqrt(2);
        % s(3) = (-1 - 1i) / sqrt(2);
        % s(4) = (1 - 1i) / sqrt(2);
        s = [1 + 1i -1 + 1i -1 - 1i 1 - 1i] / sqrt(2);
        %ss=[s(1),s(1);-1*conj(s(1)),conj(s(1))];
        min1 = 0;
        min2 = 0;
        %minn=abs(trace((y-sqrt(10^(snr/10)/2)*h*ss)*(y-sqrt(10^(snr/10)/2)*h*ss)'));
        DD = 10 ^ 10;

        for i = 1:4

            for t = 1:4
                ss = [s(i), -1 * conj(s(t)); s(t), conj(s(i))];
                yy = abs(trace((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss) * ((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss)')));

                if (yy < DD)
                    DD = yy;
                    min1 = i;
                    min2 = t;
                end

            end

        end

        u = complex([0, 0]);
        u(1) = s(min1);
        u(2) = s(min2);
        ccc1 = u;

        %defourqam
        l = length(ccc1);

        for i = 1:l

            if (ccc1(i) == (1 + 1i) / sqrt(2))
                m(2 * i - 1) = 0; m(2 * i) = 0;
            end

            if (ccc1(i) == (-1 + 1i) / sqrt(2))
                m(2 * i - 1) = 0; m(2 * i) = 1;
            end

            if (ccc1(i) == (-1 - 1i) / sqrt(2))
                m(2 * i - 1) = 1; m(2 * i) = 0;
            end

            if (ccc1(i) == (1 - 1i) / sqrt(2))
                m(2 * i - 1) = 1; m(2 * i) = 1;
            end

        end

        rcc1 = real(m);
    end

    %%4ask
    if (decode_method == 2)
        %4ask
        N = length(c1);
        n = N / 2;

        for i = 1:n

            if (c1(2 * i - 1) == 0)

                if (c1(2 * i) == 0)
                    m(i) = -1;
                else
                    m(i) = -1/3;
                end

            else

                if (c1(2 * i) == 0)
                    m(i) = 1/3;
                else
                    m(i) = 1;
                end

            end

        end

        cc1 = m;

        %Alamouti
        m1 = cc1(1);
        m2 = -conj(cc1(2));
        m3 = cc1(2);
        m4 = conj(cc1(1));
        s1 = [m1, m2; m3, m4];

        %recieve
        y1 = sqrt(10 ^ (snr / 10) / 2) * h * s1 + w;

        %decode
        s = zeros(1, 4);
        s(1) = -1;
        s(2) = -1/3;
        s(3) = 1/3;
        s(4) = 1;
        %ss=[s(1),s(1);-1*conj(s(1)),conj(s(1))];
        min1 = 0;
        min2 = 0;
        %minn=abs(trace((y-sqrt(10^(snr/10)/2)*h*ss)*(y-sqrt(10^(snr/10)/2)*h*ss)'));
        DD = 10 ^ 10;

        for i = 1:4

            for t = 1:4
                ss = [s(i), -1 * conj(s(t)); s(t), conj(s(i))];
                yy = abs(trace((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss) * ((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss)')));

                if (yy < DD)
                    DD = yy;
                    min1 = i;
                    min2 = t;
                end

            end

        end

        u = complex([0, 0]);
        u(1) = s(min1);
        u(2) = s(min2);
        ccc1 = u;

        %de4ask
        l = length(ccc1);

        for i = 1:l

            if (ccc1(i) == -1)
                m(2 * i - 1) = 0; m(2 * i) = 0;
            end

            if (ccc1(i) == -1/3)
                m(2 * i - 1) = 0; m(2 * i) = 1;
            end

            if (ccc1(i) == 1/3)
                m(2 * i - 1) = 1; m(2 * i) = 0;
            end

            if (ccc1(i) == 1)
                m(2 * i - 1) = 1; m(2 * i) = 1;
            end

        end

        rcc1 = real(m);
    end

    %%4fsk
    if (decode_method == 3)
        %4fsk
        N = length(c1);
        n = N / 2;

        for i = 1:n

            if (c1(2 * i - 1) == 0)

                if (c1(2 * i) == 0)
                    m(i) = -1;
                else
                    m(i) = -1/3;
                end

            else

                if (c1(2 * i) == 0)
                    m(i) = 1/3;
                else
                    m(i) = 1;
                end

            end

        end

        cc1 = m;

        %Alamouti
        m1 = cc1(1);
        m2 = -conj(cc1(2));
        m3 = cc1(2);
        m4 = conj(cc1(1));
        s1 = [m1, m2; m3, m4];

        %recieve
        y1 = sqrt(10 ^ (snr / 10) / 2) * h * s1 + w;

        %decode
        s = zeros(1, 4);
        s(1) = -1;
        s(2) = -1/3;
        s(3) = 1/3;
        s(4) = 1;
        %ss=[s(1),s(1);-1*conj(s(1)),conj(s(1))];
        min1 = 0;
        min2 = 0;
        %minn=abs(trace((y-sqrt(10^(snr/10)/2)*h*ss)*(y-sqrt(10^(snr/10)/2)*h*ss)'));
        DD = 10 ^ 10;

        for i = 1:4

            for t = 1:4
                ss = [s(i), -1 * conj(s(t)); s(t), conj(s(i))];
                yy = abs(trace((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss) * ((y1 - sqrt(10 ^ (snr / 10) / 2) * h * ss)')));

                if (yy < DD)
                    DD = yy;
                    min1 = i;
                    min2 = t;
                end

            end

        end

        u = complex([0, 0]);
        u(1) = s(min1);
        u(2) = s(min2);
        ccc1 = u;

        %de4fsk
        l = length(ccc1);

        for i = 1:l

            if (ccc1(i) == -1)
                m(2 * i - 1) = 0; m(2 * i) = 0;
            end

            if (ccc1(i) == -1/3)
                m(2 * i - 1) = 0; m(2 * i) = 1;
            end

            if (ccc1(i) == 1/3)
                m(2 * i - 1) = 1; m(2 * i) = 0;
            end

            if (ccc1(i) == 1)
                m(2 * i - 1) = 1; m(2 * i) = 1;
            end

        end

        rcc1 = real(m);
    end

    result = rcc1;
end
